package com.highspeed.bdk.gateway.socket.analyze.message.gui.command;

import java.util.Arrays;
import java.util.List;

/**
 * 命令管理器
 */
public class CommandManager {

    /**
     * 创建请求
     *
     * @param cmd    操作号
     * @param params 操作参数
     * @return
     */
    public static final byte[] createRequest(short cmd, List<Short> params) {
        Command command = Command.getCommand(cmd);
        Short seq = SeqGenerator.autoIncrementSeq();
        byte[] body;
        if (params == null) {
            body = new byte[0];
        } else {
            body = new byte[params.size() * 2];
        }
        byte[] header = createReqHeader(command.getCmd(), seq, body.length);
        if (params != null) {
            for (int i = 0; i < params.size(); i++) {
                short param = params.get(i);
                body[2 * i] = (byte) (param << 8);
                body[2 * i + 1] = (byte) (param << 0);
            }
        }
        body = appendBody(header, body);
        byte[] data = appendTail(body);
        return data;
    }

    /**
     * 拼接消息体尾部
     *
     * @param datas
     * @return
     */
    private static byte[] appendTail(byte[] datas) {
        byte[] bytes = Arrays.copyOf(datas, datas.length + 4);
        int len = datas.length;
        for (int i = 0; i < 4; i++) {
            bytes[len + i] = (byte) (0xAAAAAAAA >> (24 - 8 * i));
        }
        return bytes;
    }

    /**
     * 创建请求头
     *
     * @param operType    操作号，表示某种操作
     * @param reqpacketId 请求包的序列号，可以发送端是什么客户端就会回什么
     * @param length      数据包的长度
     * @return
     */
    private static byte[] createReqHeader(short operType, short reqpacketId, int length) {
        byte[] bytes = new byte[12];

        //标志位，两个字节
        bytes[0] = (byte) (0xffff >> 8);
        bytes[1] = (byte) (0xffff >> 0);

        //请求序号，两个字节
        bytes[2] = (byte) (reqpacketId >> 8);
        bytes[3] = (byte) (reqpacketId >> 0);

        //操作号，两个字节
        bytes[4] = (byte) (operType >> 8);
        bytes[5] = (byte) (operType >> 0);

        //预留字段，两个字节
        bytes[6] = (byte) (1 >> 8);
        bytes[7] = (byte) (1 >> 0);

        //数据长度，四个字节
        bytes[8] = (byte) (length >> 24);
        bytes[9] = (byte) (length >> 16);
        bytes[10] = (byte) (length >> 8);
        bytes[11] = (byte) (length >> 0);
        return bytes;
    }

    /**
     * 组装数据部分
     *
     * @param header 头部
     * @param body   数据
     * @return
     */
    private static byte[] appendBody(byte[] header, byte[] body) {
        byte[] newBytes = Arrays.copyOf(header, header.length + body.length);
        for (int i = 0; i < body.length; i++) {
            newBytes[i + header.length] = body[i];
        }
        return newBytes;
    }

}
